#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2024/3/8 17:29
# @Author  : jeff
# @FileName: jwt_utils
import jwt
import datetime
from src.utils.read_config import authentication_config
from flask import make_response, jsonify
from src.enums.status_enum import Status

REDIS_SWITCH, TIME, SECRET_KEY = authentication_config()


class JwtUtils:
    # Your key, used to sign and verify JWT, should be kept secret
    __SECRET_KEY = SECRET_KEY
    __time = TIME
    __redis_switch = REDIS_SWITCH

    @classmethod
    def create_new_token(cls, username, password):
        """
        Create a new JWT and generate jwt (token)
        :param username:
        :param password:
        :return:
        """
        # Set the validity period of JWT
        expiry_time = datetime.datetime.utcnow() + datetime.timedelta(minutes=cls.__time)

        payload = {
            'username': username,
            'password': password,
            'exp': expiry_time
        }
        # Generate JWT
        return jwt.encode(payload, cls.__SECRET_KEY, algorithm='HS256')

    @classmethod
    def renew_token(cls, token):
        try:
            # First try to decode the old token
            payload = JwtUtils.get_payload(token)
            # Check if the token has expired, may throw jwt.ExpiredSignatureError exception
            # If needed, you can add additional security checks here
            return JwtUtils.create_new_token(
                username=payload['username'],
                password=payload['password']
            )
        except jwt.ExpiredSignatureError:
            # If the old token has expired, an error message or None is returned.
            return make_response(jsonify(Status.INVALID_TOKEN.value))
        except jwt.DecodeError:
            # If the old token is invalid, return an error or None
            return make_response(jsonify(Status.INVALID_TOKEN.value))

    @classmethod
    def get_payload(cls, token):
        """
        Decode the JWT and return the payload
        Ignore expiration time：jwt.decode(token, cls.__SECRET_KEY, algorithms=['HS256'],verify=False, options={"verify_exp": False})
        :param token:
        :return:
        """
        return jwt.decode(token, cls.__SECRET_KEY, algorithms=['HS256'])
